<html>
<head><meta charset="utf-8"><title>Pre-pre RFC: track possible min and max of non-const values · t-lang · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/index.html">t-lang</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Pre-pre.20RFC.3A.20track.20possible.20min.20and.20max.20of.20non-const.20values.html">Pre-pre RFC: track possible min and max of non-const values</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="243984524"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Pre-pre%20RFC%3A%20track%20possible%20min%20and%20max%20of%20non-const%20values/near/243984524" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Bot+ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Pre-pre.20RFC.3A.20track.20possible.20min.20and.20max.20of.20non-const.20values.html#243984524">(Jun 26 2021 at 00:31)</a>:</h4>
<p>Continued from <a href="#narrow/stream/131828-t-compiler/topic/Pre-pre.20RFC.3A.20track.20possible.20min.20and.20max.20of.20unknown.20values">https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Pre-pre.20RFC.3A.20track.20possible.20min.20and.20max.20of.20unknown.20values</a></p>
<p>TL;DR How to teach compiler to automagically detect more over/underflows and conditions that are always true/false by tracking (shadowing?) the possible min and max a non-const T can have, with Default range being T::MIN..=T::MAX.</p>
<p>For example:<br>
<code>x += 3</code> would also _x_range.min = _x_range.min.saturating_add(3); _x_range.max = _x_range.max.saturating_add(3);<br>
<code>x -= 3</code> would also _x_range.min = _x_range.min.saturating_sub(3); _x_range.max = _x_range.max.saturating_sub(3);<br>
<code>x = max(x,3)</code> would also _x_range.min = max(_x_range.min, 3); _x_range.max = max(_x_range.max, _x_range.max);<br>
<code>x = min(x,3)</code> would also _x_range.max = min(_x_range.max, 3); _x_range.min = min(_x_range.max, _x_range.min);</p>
<p>While the exact value of x would remain unknown, it would be within _x_range. (Unless there are FFI boundaries, inline asm, UB or anything else that might modify T's memory directly, in which case range must be reset back to T:MIN..=T:MAX?)<br>
A smart compiler/linter/formal-verification-tool-thingy should be able to extract some value from that.</p>
<p>Maybe a clippy lint for pure functions that lack unsafe would be more a realistic dream than a mir pass...</p>



<a name="243989714"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Pre-pre%20RFC%3A%20track%20possible%20min%20and%20max%20of%20non-const%20values/near/243989714" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Pre-pre.20RFC.3A.20track.20possible.20min.20and.20max.20of.20non-const.20values.html#243989714">(Jun 26 2021 at 02:21)</a>:</h4>
<p>iirc llvm already does this</p>



<a name="243992411"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Pre-pre%20RFC%3A%20track%20possible%20min%20and%20max%20of%20non-const%20values/near/243992411" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Pre-pre.20RFC.3A.20track.20possible.20min.20and.20max.20of.20non-const.20values.html#243992411">(Jun 26 2021 at 03:36)</a>:</h4>
<p>Yes but something about the LIR we emit causes LLVM to often fail to catch this.</p>



<a name="244003346"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Pre-pre%20RFC%3A%20track%20possible%20min%20and%20max%20of%20non-const%20values/near/244003346" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Pre-pre.20RFC.3A.20track.20possible.20min.20and.20max.20of.20non-const.20values.html#244003346">(Jun 26 2021 at 08:43)</a>:</h4>
<p>there are plans for VRA (value range analysis) in MIR opts, which don't need a T-lang discussion (and already have multiple topics in <a class="stream" data-stream-id="189540" href="/#narrow/stream/189540-t-compiler.2Fwg-mir-opt">#t-compiler/wg-mir-opt</a>). Unless you are still thinking about a language level feature that happens here?</p>



<a name="244028781"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Pre-pre%20RFC%3A%20track%20possible%20min%20and%20max%20of%20non-const%20values/near/244028781" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Bot+ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Pre-pre.20RFC.3A.20track.20possible.20min.20and.20max.20of.20non-const.20values.html#244028781">(Jun 26 2021 at 18:48)</a>:</h4>
<blockquote>
<p>Unless you are still thinking about a language level feature that happens here?</p>
</blockquote>
<p>I would like to see more runtime errors become compile time errors.</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="c1">// What user sees:</span>
<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">test</span><span class="p">(</span><span class="k">mut</span><span class="w"> </span><span class="n">x</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">usize</span> <span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">max</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="n">x</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">usize</span>::<span class="n">MAX</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="n">x</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">y</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="c1">// What compiler would see:</span>
<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">test</span><span class="p">(</span><span class="k">mut</span><span class="w"> </span><span class="n">x</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">usize</span> <span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">usize</span>::<span class="n">MAX</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="n">x</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="c1">// overflow</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p><code>cargo check</code> already checks borrows, so why not check the math too?</p>



<a name="244031209"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Pre-pre%20RFC%3A%20track%20possible%20min%20and%20max%20of%20non-const%20values/near/244031209" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dirkjan Ochtman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Pre-pre.20RFC.3A.20track.20possible.20min.20and.20max.20of.20non-const.20values.html#244031209">(Jun 26 2021 at 19:46)</a>:</h4>
<p>it would be cool if this could be used for bound checks</p>



<a name="244033348"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Pre-pre%20RFC%3A%20track%20possible%20min%20and%20max%20of%20non-const%20values/near/244033348" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Pre-pre.20RFC.3A.20track.20possible.20min.20and.20max.20of.20non-const.20values.html#244033348">(Jun 26 2021 at 20:42)</a>:</h4>
<p><span class="user-mention" data-user-id="420380">@Bot+</span> , that last one doesn't seem like a very compelling example for the effort it would entail. It would only be able to error in cases where the function is guaranteed to never <strong>not</strong> overflow, when what people want is the opposite, the ability to guarantee that a function will never overflow, which needs something approaching dependent types. The earlier example, about not needing <code>_ =&gt; unreachable!()</code> when matching on const values, seems much more compelling.</p>



<a name="244041506"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Pre-pre%20RFC%3A%20track%20possible%20min%20and%20max%20of%20non-const%20values/near/244041506" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Pre-pre.20RFC.3A.20track.20possible.20min.20and.20max.20of.20non-const.20values.html#244041506">(Jun 27 2021 at 00:14)</a>:</h4>
<p><span class="user-mention silent" data-user-id="420380">Bot+</span> <a href="#narrow/stream/213817-t-lang/topic/Pre-pre.20RFC.3A.20track.20possible.20min.20and.20max.20of.20non-const.20values/near/244028781">said</a>:</p>
<blockquote>
<p>I would like to see more runtime errors become compile time errors.</p>
</blockquote>
<p>Note that, from a <em>specification</em> perspective, I don't think I'd want that kind of value range analysis to be a hard error.  I don't want to <em>require</em> that we always do that as part of compilation (the way we do for things like borrowck).</p>
<p>As a lint, though, sure.</p>



<a name="244044718"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Pre-pre%20RFC%3A%20track%20possible%20min%20and%20max%20of%20non-const%20values/near/244044718" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Bot+ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Pre-pre.20RFC.3A.20track.20possible.20min.20and.20max.20of.20non-const.20values.html#244044718">(Jun 27 2021 at 01:58)</a>:</h4>
<p>We alrady have std::num::Wrapping and T.wrapping_mul to give compiler permission to overflow.</p>
<p>I'd argue unintentional underflows in business logic can be just as bad or worse than memory errors.</p>
<p>I agree making detectable wraparounds hard errors is big enough change spec-wise to warrant edition change (Rust 2024?), and if the analysis proves to be too expensive then a lint is fine too.</p>



<a name="244048187"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Pre-pre%20RFC%3A%20track%20possible%20min%20and%20max%20of%20non-const%20values/near/244048187" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Pre-pre.20RFC.3A.20track.20possible.20min.20and.20max.20of.20non-const.20values.html#244048187">(Jun 27 2021 at 03:55)</a>:</h4>
<p>The point is that erroring for <em>potential</em> overflows is impractically aggressive.  And for <em>guaranteed</em> overflows it's too restrictive to bother.  Thus you're left with a heuristic in the middle, which is territory for lints -- maybe even deny-by-default lints -- but not hard errors.</p>



<a name="244048238"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Pre-pre%20RFC%3A%20track%20possible%20min%20and%20max%20of%20non-const%20values/near/244048238" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Pre-pre.20RFC.3A.20track.20possible.20min.20and.20max.20of.20non-const.20values.html#244048238">(Jun 27 2021 at 03:56)</a>:</h4>
<p><span class="user-mention silent" data-user-id="420380">Bot+</span> <a href="#narrow/stream/213817-t-lang/topic/Pre-pre.20RFC.3A.20track.20possible.20min.20and.20max.20of.20non-const.20values/near/244044718">said</a>:</p>
<blockquote>
<p>I'd argue unintentional underflows in business logic can be just as bad or worse than memory errors.</p>
</blockquote>
<p>It's not.  The problem with UB is that it ruins your capacity to reason about the behaviour of your program.</p>
<p>You can reason about overflows, you can test for overflows, you can debug overflows.  The compiler will never catch all errors.  Remember, it's "safe" code to delete all your files, or upload your banking cookies to pastebin.</p>



<a name="244048411"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Pre-pre%20RFC%3A%20track%20possible%20min%20and%20max%20of%20non-const%20values/near/244048411" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Pre-pre.20RFC.3A.20track.20possible.20min.20and.20max.20of.20non-const.20values.html#244048411">(Jun 27 2021 at 04:02)</a>:</h4>
<p>yeah safe doesn't mean correct, it just means comprehensible</p>



<a name="244048958"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Pre-pre%20RFC%3A%20track%20possible%20min%20and%20max%20of%20non-const%20values/near/244048958" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Bot+ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Pre-pre.20RFC.3A.20track.20possible.20min.20and.20max.20of.20non-const.20values.html#244048958">(Jun 27 2021 at 04:23)</a>:</h4>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#![feature(unchecked_math)]</span><span class="w"></span>
<span class="k">use</span><span class="w"> </span><span class="n">core</span>::<span class="n">cmp</span>::<span class="p">{</span><span class="n">max</span><span class="p">,</span><span class="n">min</span><span class="p">};</span><span class="w"></span>
<span class="k">use</span><span class="w"> </span><span class="n">core</span>::<span class="n">ops</span>::<span class="n">RangeInclusive</span><span class="p">;</span><span class="w"></span>

<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">test</span><span class="p">(</span><span class="k">mut</span><span class="w"> </span><span class="n">x</span>: <span class="kt">usize</span><span class="p">,</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">y</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">usize</span> <span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">min</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">min</span><span class="p">(</span><span class="kt">usize</span>::<span class="n">MAX</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="n">x</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">y</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">_test</span><span class="p">(</span><span class="k">mut</span><span class="w"> </span><span class="n">x</span>: <span class="kt">usize</span><span class="p">,</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">y</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">usize</span> <span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">_x</span>: <span class="nc">RangeInclusive</span><span class="o">&lt;</span><span class="kt">usize</span><span class="o">&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">RangeInclusive</span>::<span class="n">new</span><span class="p">(</span><span class="kt">usize</span>::<span class="n">MIN</span><span class="p">,</span><span class="w"> </span><span class="kt">usize</span>::<span class="n">MAX</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">_y</span>: <span class="nc">RangeInclusive</span><span class="o">&lt;</span><span class="kt">usize</span><span class="o">&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">RangeInclusive</span>::<span class="n">new</span><span class="p">(</span><span class="kt">usize</span>::<span class="n">MIN</span><span class="p">,</span><span class="w"> </span><span class="kt">usize</span>::<span class="n">MAX</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">"x: {:#?}"</span><span class="p">,</span><span class="w"> </span><span class="n">_x</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">"y: {:#?}"</span><span class="p">,</span><span class="w"> </span><span class="n">_y</span><span class="p">);</span><span class="w"></span>

<span class="w">    </span><span class="k">const</span><span class="w"> </span><span class="n">t0</span>: <span class="kt">usize</span> <span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">min</span><span class="p">(</span><span class="n">t0</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="n">_x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">RangeInclusive</span>::<span class="n">new</span><span class="p">(</span><span class="n">min</span><span class="p">(</span><span class="o">*</span><span class="n">_x</span><span class="p">.</span><span class="n">start</span><span class="p">(),</span><span class="w"> </span><span class="n">t0</span><span class="p">),</span><span class="w"> </span><span class="n">t0</span><span class="p">);</span><span class="w"></span>

<span class="w">    </span><span class="k">const</span><span class="w"> </span><span class="n">t1</span>: <span class="kt">usize</span> <span class="o">=</span><span class="w"> </span><span class="kt">usize</span>::<span class="n">MAX</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">min</span><span class="p">(</span><span class="n">t1</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="n">_y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">RangeInclusive</span>::<span class="n">new</span><span class="p">(</span><span class="n">min</span><span class="p">(</span><span class="o">*</span><span class="n">_y</span><span class="p">.</span><span class="n">start</span><span class="p">(),</span><span class="w"> </span><span class="n">t1</span><span class="p">),</span><span class="w"> </span><span class="n">t1</span><span class="p">);</span><span class="w"></span>

<span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">"x: {:#?}"</span><span class="p">,</span><span class="w"> </span><span class="n">_x</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">"y: {:#?}"</span><span class="p">,</span><span class="w"> </span><span class="n">_y</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="n">_x</span><span class="p">.</span><span class="n">end</span><span class="p">().</span><span class="n">checked_mul</span><span class="p">(</span><span class="o">*</span><span class="n">_y</span><span class="p">.</span><span class="n">end</span><span class="p">()).</span><span class="n">is_some</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="c1">// SAFETY: Never overflows</span>
<span class="w">        </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">x</span><span class="p">.</span><span class="n">unchecked_mul</span><span class="p">(</span><span class="n">y</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">_x</span><span class="p">.</span><span class="n">start</span><span class="p">().</span><span class="n">checked_mul</span><span class="p">(</span><span class="o">*</span><span class="n">_y</span><span class="p">.</span><span class="n">start</span><span class="p">()).</span><span class="n">is_none</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="fm">panic!</span><span class="p">(</span><span class="s">"Always overflows"</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">x</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="c1">// Warning: May overflow</span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>Example is simplified because to handle wrapping types, range would actually have to be something like</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">enum</span> <span class="nc">ValueRange</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">Include</span><span class="p">(</span><span class="n">RangeInclusive</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">),</span><span class="w"> </span><span class="c1">// min..=max</span>
<span class="w">    </span><span class="n">Exclude</span><span class="p">(</span><span class="n">RangeInclusive</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">),</span><span class="w"> </span><span class="c1">// T:MIN..=min OR max..=T:MAX</span>
<span class="w">    </span><span class="n">Constant</span><span class="p">(</span><span class="n">T</span><span class="p">),</span><span class="w"> </span><span class="c1">// min == max</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="244049304"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Pre-pre%20RFC%3A%20track%20possible%20min%20and%20max%20of%20non-const%20values/near/244049304" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Pre-pre.20RFC.3A.20track.20possible.20min.20and.20max.20of.20non-const.20values.html#244049304">(Jun 27 2021 at 04:35)</a>:</h4>
<p>Wrapping and such are pure debugging aides designed as part of the compiler and should not be seen as a deep precedent for later design, IMO, because they are a cure almost as painful as the problem.</p>



<a name="244131494"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Pre-pre%20RFC%3A%20track%20possible%20min%20and%20max%20of%20non-const%20values/near/244131494" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Pre-pre.20RFC.3A.20track.20possible.20min.20and.20max.20of.20non-const.20values.html#244131494">(Jun 28 2021 at 11:36)</a>:</h4>
<p>rfc 1229 says we can't hard error, but we are allowed to lint</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>